Conditions | 13 |
Total Lines | 68 |
Code Lines | 59 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like WebSocketClient.initSocket often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | import './types' |
||
51 | |||
52 | private initSocket(ws: wsc.Socket) { |
||
53 | const {queue, config} = this |
||
54 | this.open = true |
||
55 | this.ws = ws |
||
56 | this.onReadyQueue.forEach((fn: Function) => fn()) |
||
57 | this.onReadyQueue.splice(0) |
||
58 | const {id_key, data_key} = config.server |
||
59 | // Works also on previously opened sockets that do not fire 'open' event. |
||
60 | this.call('open', ws) |
||
61 | for(const msg_id in queue) ws.send(queue[msg_id].msg) |
||
62 | if(this.reconnect_timeout !== null) { |
||
63 | clearInterval(this.reconnect_timeout) |
||
64 | this.reconnect_timeout = null |
||
65 | } |
||
66 | if(config.ping) { |
||
67 | const ping_interval = setInterval(() => { |
||
68 | if(this.open) this.send(config.ping.content) |
||
69 | if(this.forcibly_closed) clearInterval(ping_interval) |
||
70 | }, config.ping.interval*1e3) |
||
71 | } |
||
72 | add_event(ws, 'close', async (...e) => { |
||
73 | this.log('close') |
||
74 | this.open = false |
||
75 | this.ws = null |
||
76 | this.onCloseQueue.forEach((fn: Function) => fn()) |
||
77 | this.onCloseQueue.splice(0) |
||
78 | this.call('close', ...e) |
||
79 | // Auto reconnect. |
||
80 | const reconnect = config.reconnect |
||
81 | if( |
||
82 | typeof reconnect === 'number' && |
||
83 | !isNaN(reconnect) && |
||
84 | !this.forcibly_closed |
||
85 | ) { |
||
86 | const reconnectFunc = async () => { |
||
87 | this.log('reconnect') |
||
88 | if(this.ws !== null) { |
||
89 | this.ws.close() |
||
90 | this.ws = null |
||
91 | } |
||
92 | // If some error occured, try again. |
||
93 | const status = await this.connect() |
||
94 | if(status !== null) |
||
95 | this.reconnect_timeout = setTimeout(reconnectFunc, reconnect * 1000) |
||
96 | } |
||
97 | // TODO: test normal close by server. Would it be infinite ? |
||
98 | reconnectFunc() |
||
99 | } |
||
100 | // reset the flag to reuse. |
||
101 | this.forcibly_closed = false |
||
102 | }) |
||
103 | add_event(ws, 'message', (e) => { |
||
104 | try { |
||
105 | const data = config.decode(e.data) |
||
106 | this.call('message', {...e, data}) |
||
107 | if(data[id_key]) { |
||
108 | const q = this.queue[data[id_key]] |
||
109 | if(q) { |
||
110 | // Debug, Log. |
||
111 | const time = q.sent_time ? (Date.now() - q.sent_time) : null |
||
112 | this.log('message', data[data_key], time) |
||
113 | // Play. |
||
114 | q.ff(data[data_key]) |
||
115 | } |
||
116 | } |
||
117 | } catch (err) { |
||
118 | console.error(err, `WSP: Decode error. Got: ${e.data}`) |
||
119 | } |
||
265 | export default WebSocketClient |